﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using SGLisp;

public class Actor : MonoBehaviour
{
    Unit mUnit;
    public Unit Unit { get { return mUnit; } }
    public Context mContext;
    Animation mAnimation;
    public Animation Animation { get { return mAnimation; } }
    public Dictionary<string, List<IFunction>> mActorEvents = new Dictionary<string, List<IFunction>>();

    public static Actor Create(string actorName, Unit unit)
    {
        Hashtable actorTable = (Hashtable)Game.Inst.Table.ActorTable[actorName];

        GameObject newActorG = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>((string)actorTable[":prefab"]));
        newActorG.transform.SetParent(unit.transform,false);
        Actor newActor = newActorG.AddComponent<Actor>();
        newActor.Init(actorTable, unit);
        return newActor;
    }

    public void Init(Hashtable tableData, Unit unit)
    {
        mContext = new Context(unit.Context);
        mContext.Define("actor",new ObjectNode(this));
        mAnimation = gameObject.GetComponent<Animation>();

        this.mUnit = unit;
        if (tableData.ContainsKey(":unit-events") == false) return;
        Hashtable eventDic = (Hashtable)tableData[":unit-events"];
        foreach (DictionaryEntry eventItem in eventDic)
        {
            string eventName = (string)eventItem.Key;
            this.AddActorEvent(eventName, (IFunction)eventItem.Value);
            this.mUnit.Event.AddEventHandler(eventName, this.onUnitEvent);
        }
    }

    public void AddActorEvent(string eventName, IFunction fn)
    {
        if (!this.mActorEvents.ContainsKey(eventName))
        {
            this.mActorEvents.Add(eventName, new List<IFunction>());
        }
        this.mActorEvents[eventName].Add(fn);
    }

    void onUnitEvent(string eventName,params object[] args)
    {
        List<ASTNode> Args = new List<ASTNode>();
        for (int i=0;i<args.Length;i++)
        {
            if (args[i] is string)
            {
                Args.Add(new StringNode((string)args[i]));
            }
            else if (args[i] is int)
            {
                Args.Add(new NumberNode((int)args[i]));
            }
        }
       
        List<IFunction> curEvents = this.mActorEvents[eventName];
        for (int i = 0; i < curEvents.Count; i++)
        {
            curEvents[i].Exec(Args, this.mContext);
        }
    }
}
